package mongo

import (
	"context"
	"gogo/log"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
)

func (c *Mongo_Class) FindOneAndUpdate(db_name, table_name string, filter interface{}, update interface{}, opts ...interface{}) *mongo.SingleResult {
	if ret := c.UtilsMongoShell(db_name, table_name, Action_FindOneAndUpdate, filter, update, opts...); ret != nil {
		return ret.(*mongo.SingleResult)
	}

	return nil
}

func (c *Mongo_Class) FindOne(db_name, table_name string, filter interface{}, opts ...interface{}) *mongo.SingleResult {
	if ret := c.UtilsMongoShell(db_name, table_name, Action_FindOne, filter, nil, opts...); ret != nil {
		return ret.(*mongo.SingleResult)
	}

	return nil
}

func (c *Mongo_Class) Find(db_name, table_name string, filter interface{}, opts ...interface{}) []map[string]interface{} {

	if ret := c.UtilsMongoShell(db_name, table_name, Action_Find, filter, nil, opts...); ret != nil {
		cursor := ret.(*mongo.Cursor)

		defer cursor.Close(context.Background())

		results := []map[string]interface{}{}

		for cursor.Next(context.Background()) {
			var result map[string]interface{}
			if err := cursor.Decode(&result); err != nil {
				log.This().ErrorF("Find: %s", err)
			} else {
				results = append(results, result)
			}
		}

		return results
	}

	return nil
}

func (c *Mongo_Class) Find2Raw(db_name, table_name string, filter interface{}, opts ...interface{}) []bson.Raw {

	if ret := c.UtilsMongoShell(db_name, table_name, Action_Find, filter, nil, opts...); ret != nil {
		cursor := ret.(*mongo.Cursor)

		defer cursor.Close(context.Background())

		var results []bson.Raw

		for cursor.Next(context.Background()) {
			results = append(results, cursor.Current)
		}

		return results
	}

	return nil
}

func (c *Mongo_Class) Distinct(db_name, table_name string, filed_name string, filter interface{}, opts ...interface{}) []interface{} {
	if data_list := c.UtilsMongoShell(db_name, table_name, Action_Distinct, filter, filed_name, opts...); data_list != nil {
		return data_list.([]interface{})
	}

	return nil
}

func (c *Mongo_Class) CountDocuments(db_name, table_name string, filter interface{}) int64 {
	if ret := c.UtilsMongoShell(db_name, table_name, Action_CountDocuments, filter, nil); ret != nil {
		return ret.(int64)
	}
	return -1
}
